package org.phytodata.actionengine;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.pentaho.actionsequence.dom.actions.ActionFactory;
import org.pentaho.platform.api.action.IAction;
import org.pentaho.platform.api.engine.IComponent;
import org.pentaho.platform.api.engine.IPluginManager;
import org.pentaho.platform.engine.core.system.PentahoSystem;
import org.phytodata.actionengine.util.LegacyEngineUtil;
import org.springframework.beans.factory.BeanFactoryUtils;
import org.springframework.beans.factory.ListableBeanFactory;

public class ActionEngine {
  protected IPluginManager pluginMgr = PentahoSystem.get(IPluginManager.class);
  private static final Log log = LogFactory.getLog(ActionEngine.class);
  
  @SuppressWarnings("unchecked")
  public List<ActionInfo> getActionInfos() {
    ArrayList<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
    for(String pluginId : pluginMgr.getRegisteredPlugins()) {
      ListableBeanFactory pluginBeanFactory = pluginMgr.getBeanFactory(pluginId);
      Map<String, IAction> actions = BeanFactoryUtils.beansOfTypeIncludingAncestors(pluginBeanFactory, IAction.class);
      for(Map.Entry<String, IAction> entry : actions.entrySet()) {
        ActionInfo actionInfo = new ActionInfo(pluginId, entry.getKey(), entry.getValue().getClass().getName(), "Action Bean (IAction)");
        actionInfos.add(actionInfo);
      }
    }
    
    //add all the native (non-plugin IActions, PojoComponents, and BIComponents)
    actionInfos.addAll(getNativeBIComponentInfos());
    
    return actionInfos;
  }
  
  @SuppressWarnings("unchecked")
  protected Map<String, Class> getNativeBIComponents() {
    ActionFactory.getActionDefinition("DNE"); //prime the factory to load the definitions
    return ActionFactory.pluginActions;
  }
  
  protected List<ActionInfo> getNativeBIComponentInfos() {
    ActionFactory.getActionDefinition("DNE"); //prime the factory to load the definitions
    
    ArrayList<ActionInfo> actionInfos = new ArrayList<ActionInfo>();
    for(Map.Entry<String, String> entry : LegacyEngineUtil.getLegacyComponents().entrySet()) {
      String classname = entry.getValue();
      boolean deprecated = false;
      if(classname.startsWith("!")) {
        deprecated = true;
        classname = classname.substring(1);
      }
      
      Class<?> clazz;
      try {
        clazz = Class.forName(classname);
      } catch (ClassNotFoundException e) {
        log.warn("Failed to load class for name "+classname, e);
        continue;
      }
      String type = null;
      if(IAction.class.isAssignableFrom(clazz)) {
        type = "Action Bean (IAction)";
      }
      else if(IComponent.class.isAssignableFrom(clazz)) {
        type = "Legacy Component (IComponent)";
      }
      else {
        type = "Legacy Bean";
      }
      ActionInfo actionInfo = new ActionInfo("[NATIVE]", entry.getKey(), clazz.getName(), type);
      actionInfo.setDeprecated(deprecated);
      actionInfos.add(actionInfo);
    }
    
    return actionInfos;
  }
  
//  public List<IAction> getActions() {
//    
//  }
//    for(String pluginId : pluginMgr.getRegisteredPlugins()) {
//      ListableBeanFactory pluginBeanFactory = pluginMgr.getBeanFactory(pluginId);
//      Map<String, IAction> actions = BeanFactoryUtils.beansOfTypeIncludingAncestors(pluginBeanFactory, IAction.class);
//      for(Map.Entry<String, IAction> entry : actions.entrySet()) {
//        ActionInfo actionInfo = new ActionInfo();
//        populate(entry.getValue(), entry.getKey(), actionInfo, pluginId);
//        actionInfos.add(actionInfo);
//      }
//  }
}
